package com.botarena.client.contest;

import java.util.ArrayList;
import java.util.List;

import com.botarena.client.UIHelper;
import com.botarena.client.contest.remote.ContestAccess;
import com.botarena.client.contest.remote.ContestAccessAsync;
import com.botarena.client.ui.StringHelper;
import com.botarena.shared.RankInfo;
import com.google.gwt.core.client.GWT;
import com.google.gwt.user.cellview.client.CellTable;
import com.google.gwt.user.cellview.client.SimplePager;
import com.google.gwt.user.cellview.client.TextColumn;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.Composite;
import com.google.gwt.user.client.ui.HasHorizontalAlignment;
import com.google.gwt.user.client.ui.HasVerticalAlignment;
import com.google.gwt.user.client.ui.HorizontalPanel;
import com.google.gwt.user.client.ui.InlineLabel;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.VerticalPanel;
import com.google.gwt.view.client.Range;
import com.google.gwt.view.client.RangeChangeEvent;

/**
 * Strona rankingu
 * 
 * @author wirenth
 * 
 */
public class RankingPanel extends Composite {

	/*
	 * public static List<RankInfo> RANK_SAMPLE = Arrays.asList( new RankInfo(1,
	 * "bot12", "Zenek", 1000, 234, 1122), new RankInfo(2,"bot3", "Zdzisio",
	 * 900, 300, 1096), new RankInfo(3,"bot3", "Zdzisio", 900, 300, 1096));
	 * 
	 * 
	 * public static List<RankInfo> RANK_SAMPLE2 = Arrays.asList( new
	 * RankInfo(4,"bot3", "Zdzisio", 900, 300, 1096), new RankInfo(5,"bot3",
	 * "Zdzisio", 900, 300, 1096));
	 */

	public static final int PAGE_SIZE = 10; // possibly changed from GUI at some
											// point?

	CellTable<RankInfo> rankingTable;

	List<RankInfo> data;

	SimplePager pager;

	public RankingPanel() {

		VerticalPanel mainPanel = new VerticalPanel();
		mainPanel.setWidth("100%");
		mainPanel.setSpacing(15);
		initWidget(mainPanel);

		Label title = new Label("Ranking");
		title.setStyleName("title");
		mainPanel.add(title);

		rankingTable = new CellTable<RankInfo>();

		buildColumnModel(rankingTable);
		// rankingTable.setRowCount(3);
		// rankingTable.setRowData(RANK_SAMPLE);

		mainPanel.add(rankingTable);
		mainPanel.setCellHorizontalAlignment(rankingTable,
				HasHorizontalAlignment.ALIGN_CENTER);
		rankingTable.setWidth("100%");

		HorizontalPanel bottomPanel = new HorizontalPanel();
		bottomPanel.setWidth("100%");
		bottomPanel.setSpacing(20);
		mainPanel.add(bottomPanel);

		pager = createPager(rankingTable);
		bottomPanel.add(pager);
		bottomPanel.setCellVerticalAlignment(pager,
				HasVerticalAlignment.ALIGN_MIDDLE);

		InlineLabel filling = new InlineLabel();
		bottomPanel.add(filling);

		Button findBots = new Button("Find my bots");
		bottomPanel.add(findBots);
		bottomPanel.setCellHorizontalAlignment(findBots,
				HasHorizontalAlignment.ALIGN_RIGHT);
		bottomPanel.setCellVerticalAlignment(findBots,
				HasVerticalAlignment.ALIGN_MIDDLE);

		Label comment = new Label("W - wins, L - losses, D - draw");
		comment.setStyleName("commentSmall");
		mainPanel.add(comment);
	}

	public void setRankingData(List<RankInfo> data) {
		this.data = data;
		rankingTable.setRowCount(data.size());
		rankingTable.setRowData(data);
		pager.setPageSize(RankingPanel.PAGE_SIZE);
		addRangeHandler();
	}

	private void addRangeHandler() {
		rankingTable.addRangeChangeHandler(new RangeChangeEvent.Handler() {

			@Override
			public void onRangeChange(RangeChangeEvent event) {
				Range range = rankingTable.getVisibleRange();
				final int start = range.getStart();
				int length = range.getLength();
				final List<RankInfo> res = new ArrayList<RankInfo>(length);
				List<String> keys = new ArrayList<String>(length);
				for (int i = start; i < start + length && i < data.size() + 2; i++)
					keys.add(data.get(i).key);
				ContestAccessAsync daa = GWT.create(ContestAccess.class);
				daa.getRankPart(keys, new AsyncCallback<List<RankInfo>>() {

					@Override
					public void onSuccess(List<RankInfo> result) {
						int pos = start;
						for (RankInfo rank : result) {
							rank.pos = pos;
							pos++;
							res.add(rank);
						}

						rankingTable.setRowData(start, res);
					}

					@Override
					public void onFailure(Throwable caught) {
						// TODO ?
						caught.printStackTrace();
					}
				});

			}
		});
	}

	private SimplePager createPager(final CellTable<RankInfo> rankingTable) {
		SimplePager pager = new SimplePager();
		pager.setDisplay(rankingTable);

		return pager;
	}

	private void buildColumnModel(CellTable<RankInfo> rankingTable) {
		TextColumn<RankInfo> posCol = new TextColumn<RankInfo>() {
			@Override
			public String getValue(RankInfo pos) {
				return "" + (pos.pos + 1);
			}
		};
		rankingTable.addColumn(posCol, "POSITION");

		TextColumn<RankInfo> botNameCol = new TextColumn<RankInfo>() {
			@Override
			public String getValue(RankInfo pos) {
				return StringHelper.limitedLengthString(pos.botName,
						UIHelper.MAX_NAME_LEN_BIG);
			}
		};
		rankingTable.addColumn(botNameCol, "BOT NAME");

		TextColumn<RankInfo> userNameCol = new TextColumn<RankInfo>() {
			@Override
			public String getValue(RankInfo pos) {
				return StringHelper.limitedLengthString(pos.userName,
						UIHelper.MAX_NAME_LEN_BIG);
			}
		};
		rankingTable.addColumn(userNameCol, "USER NAME");

		TextColumn<RankInfo> fightStatCol = new TextColumn<RankInfo>() {
			@Override
			public String getValue(RankInfo pos) {
				StringBuffer buf = new StringBuffer();
				buf.append(pos.fightWon).append(":").append(pos.fightLost)
						.append(":").append(pos.fightDraw);
				return buf.toString();
			}
		};
		rankingTable.addColumn(fightStatCol, "FIGHT STATS (W:L:D)");

		TextColumn<RankInfo> rankCol = new TextColumn<RankInfo>() {
			@Override
			public String getValue(RankInfo pos) {
				return "" + pos.rank;
			}
		};
		rankingTable.addColumn(rankCol, "RANK");
	}

}
